using System;
using System.Threading;
using OracleInternal.Common;
using OracleInternal.ServiceObjects;

namespace OracleInternal.ConnectionPool
{
	internal class ServiceCtx
	{
		internal string m_databaseName;

		internal ManualResetEventSlim m_serviceUpEvent = new ManualResetEventSlim(initialState: true);

		internal DateTime m_serviceDownTime = DateTime.Now;

		internal bool m_bWaitedForSvcReloc;

		internal RoundRobin m_roundRobin = new RoundRobin();

		internal OracleGlobalizationImpl m_orclGlobImpl;

		internal bool m_serviceDown;

		internal SyncQueueList<string> m_serviceMemberDownInstNames = new SyncQueueList<string>();

		internal DateTime m_serviceMemberDownLastUpdateUtcTime = DateTime.Now;

		internal DateTime m_serviceDownLastUpdateUtcTime = DateTime.Now;

		internal object m_sync = new object();

		internal string m_serviceName;

		internal ServiceCtx(string serviceName)
		{
			m_serviceName = serviceName;
		}

		internal void CheckAndUpdateServiceMemberDOWNNames_RLB(RLB rlb)
		{
			if (rlb.m_lastUpdateTime.CompareTo(m_serviceDownLastUpdateUtcTime) >= 0)
			{
				lock (m_sync)
				{
					if (rlb.m_lastUpdateTime.CompareTo(m_serviceDownLastUpdateUtcTime) >= 0 && rlb.m_instances.Length != 0)
					{
						m_serviceDown = false;
						m_serviceDownLastUpdateUtcTime = rlb.m_lastUpdateTime;
					}
				}
			}
			if (rlb.m_lastUpdateTime.CompareTo(m_serviceMemberDownLastUpdateUtcTime) < 0)
			{
				return;
			}
			lock (m_sync)
			{
				if (rlb.m_lastUpdateTime.CompareTo(m_serviceMemberDownLastUpdateUtcTime) < 0)
				{
					return;
				}
				for (int i = 0; i < rlb.m_instances.Length; i++)
				{
					string t = rlb.m_instances[i].ToLowerInvariant();
					if (m_serviceMemberDownInstNames.IndexOf(t) >= 0)
					{
						m_serviceMemberDownInstNames.Remove(t);
					}
				}
				m_serviceMemberDownLastUpdateUtcTime = rlb.m_lastUpdateTime;
			}
		}

		internal void CheckAndUpdateServiceMemberDOWNNames_HA(string instName, bool serviceMemberDown, DateTime eventTime)
		{
			if (eventTime.CompareTo(m_serviceMemberDownLastUpdateUtcTime) < 0)
			{
				return;
			}
			lock (m_sync)
			{
				if (eventTime.CompareTo(m_serviceMemberDownLastUpdateUtcTime) >= 0)
				{
					if (serviceMemberDown)
					{
						m_serviceMemberDownInstNames.AddIfNotExist(instName);
						m_serviceMemberDownLastUpdateUtcTime = eventTime;
					}
					else
					{
						m_serviceMemberDownInstNames.Remove(instName);
						m_serviceMemberDownLastUpdateUtcTime = eventTime;
						m_serviceDown = false;
					}
				}
			}
		}

		internal void UpdateServiceDown(bool isServiceDown, DateTime eventTime)
		{
			if (eventTime.CompareTo(m_serviceDownLastUpdateUtcTime) < 0)
			{
				return;
			}
			lock (m_sync)
			{
				if (eventTime.CompareTo(m_serviceDownLastUpdateUtcTime) >= 0)
				{
					m_serviceDown = isServiceDown;
					m_serviceDownLastUpdateUtcTime = eventTime;
				}
			}
		}
	}
}
